package cn.com.colasoft.generics;

import java.lang.reflect.*;
import java.util.List;

/**
 * 泛型数组，描述的是形如：A<T>[]或T[]类型变量和原始类型
 * 并不是我们工作中所使用的数组String[] 、byte[]（这种都属于Class），而是带有泛型的数组，即T[] 泛型数组
 *
 * 分析：GenericArrayType有两个都是：List<String>[] pTypeArray, T[] vTypeArray它哥俩都是泛型数组。但是这两String[] strings, Main[] test可不是，他俩属于Class普通类型
 * genericArrayType.getGenericComponentType()返回的类型为ParameterizedTypeImpl类型，能够获取到数组的实际参数类型
 */
public class GenericArrayTypeTest<T extends Number> {

    // 这里面有各种各样的数组：各有不同 方便看测试效果
    // 含有泛型数组的才是GenericArrayType
    public void testGenericArrayType(List<String>[] pTypeArray, // GenericArrayType
                                     T[] vTypeArray, // GenericArrayType
                                     List<String> list, // ParameterizedType
                                     List<? extends Number> wildcardList, // ParameterizedType
                                     String[] strings, // Class
                                     GenericArrayTypeTest[] test // Class
    ) {}


    public static void main(String[] args) {
        // GenericArrayTypeTest.class.getDeclaredMethods();
        Method[] declaredMethods = new GenericArrayTypeTest<Number>().getClass().getDeclaredMethods();
        for (Method method : declaredMethods) {
            // main方法不用处理
            if (method.getName().startsWith("main")) {
                continue;
            }

            // 开始处理该方法===打印出此方法签名
            System.out.println("declare Method:" + method);

            // 该方法能获取到该方法所有的实际的参数化类型，比如本例中有五个参数，那数组长度就是5
            Type[] types = method.getGenericParameterTypes();

            // 分组打印出来
            for (Type type : types) {

                if (type instanceof ParameterizedType) {
                    System.out.println("------------------------------");
                    ParameterizedType parameterizedType = (ParameterizedType) type;
                    System.out.println("ParameterizedType type :" + parameterizedType);
                } else if (type instanceof GenericArrayType) {
                    System.out.println("------------------------------");
                    GenericArrayType genericArrayType = (GenericArrayType) type;
                    System.out.println("GenericArrayType type :" + genericArrayType);

                    Type genericComponentType = genericArrayType.getGenericComponentType();
                    System.out.println("genericComponentType:" + genericComponentType);
                } else if (type instanceof WildcardType) {
                    System.out.println("------------------------------");
                    WildcardType wildcardType = (WildcardType) type;
                    System.out.println("WildcardType type :" + wildcardType);
                } else if (type instanceof TypeVariable) {
                    System.out.println("------------------------------");
                    TypeVariable typeVariable = (TypeVariable) type;
                    System.out.println("TypeVariable type :" + typeVariable);
                } else {
                    System.out.println("------------------------------");
                    Class clazz = (Class) type;
                    System.out.println("type :" + clazz);
                }
            }
        }
    }

}
